sap.designstudio.sdk.PropertyPage.subclass("com.justbi.view.ViewPropertyPage", function() {
  var that = this;
  
  
  this.init = function() {    
    setTimeout(function(){
      addEventListeners();
    }, 1000);
    
  };
  
  this.componentSelected = function(){
    $( "body" ).unbind("reloadExamples");
    $( "body" ).on('reloadExamples', function() {
      addEventListeners();
    });
    
    addEventListeners();
  };
  
  
  function addEventListeners(){
    /**
     * UPDATE BUTTON --> DEVELOPER
     */
    $( "#btnUpdateDeveloper" ).unbind("click");
    $( "#btnUpdateDeveloper" ).click(function() {
      
      // make sure that the entered text in the editors are stored
      var propertyArray = ["configString", "htmlString", "cssString", "jsString"];
      that.firePropertiesChanged(propertyArray);
      
      // re-generate support view (if available)
      generateSupportView(true);
    });
    
    // generate the support view
    generateSupportView();
  }
  

  

  
  function createComponentSelectorTree(){
    
    if (!(typeof getPredefinedComponentTree === 'function')) { 
      $('#componentselector').html("<p style='color:red;margin-left:10px;margin-top:10px;'><b>No predefined components found.</b><br><br>Make sure that the URL defined in the settings is correct and can be reached.</p>");
      return;
    }
    
    // build the tree with predefined components
    var jstreeConfig = getPredefinedComponentTree();
    $('#componentselector').jstree( jstreeConfig );
    
    // add an event listener for the update button
    $("#btnUpdateSupport").unbind("click");
    $("#btnUpdateSupport").click(function () {
      if (!(typeof getPredefinedComponentById === 'function')) { 
        alert('An error occured when trying to retrieve the predefined component.');
        return;
      }
      
      // get the selected node
      var nodeId = $("#componentselector").jstree("get_selected")[0];
      if(nodeId === undefined || nodeId === null || nodeId === ""){
        return;
      }
      
      // get the component configuration
      var componentConfig = getPredefinedComponentById(nodeId);
      
      // config / html / javascript / css
      editor = ace.edit("editor_config"),
      editor.getSession().setValue( componentConfig.config );
      editor = ace.edit("editor_html"),
      editor.getSession().setValue( componentConfig.html );
      editor = ace.edit("editor_javascript"),
      editor.getSession().setValue( componentConfig.js );
      editor = ace.edit("editor_css"),
      editor.getSession().setValue( componentConfig.css );
      
      // simulate the developer update click
      $("#btnUpdateDeveloper").click();
      
      createSupportView();
    });
  }

  
  
  function createSupportView(){
    var configObject = {},
      editor = ace.edit("editor_config"),
      generateInitialPropertyInterface = false;
    
    // check if a valid propertyInterface is available
    try{
      configObject = JSON.parse( editor.getSession().getValue() );
      if(configObject.propertyInterface === undefined || configObject.propertyInterface === null){
        generateInitialPropertyInterface = true;
      }
    }catch(error){
      generateInitialPropertyInterface = true;
    }
    
    // if no propertInterface is available, generate one
    if(generateInitialPropertyInterface){
      //configObject.propertyInterface = generateInitPropInterface();
      $("#componentselector").show();
      $("#alpacaform").hide();
      
      // show the component selector
      createComponentSelectorTree();
      return;
    }
    
    // make sure that the right div is displayed
    $("#componentselector").hide();
    $("#alpacaform").show();
    
    // create a callback function for the submit button in the support view
    var postRendercb = function (renderedForm) {
      $("#btnUpdateSupport").unbind("click");
      $("#btnUpdateSupport").click(function () {
          // merge the properties with the config string
          //$().extend(true, configObject.properties, renderedForm.getValue() );
          
          configObject.propertyInterface.data = renderedForm.getValue();
          editor.getSession().setValue( JSON.stringify(configObject, undefined, 4) );
          
          // update the property
          var propertyArray = ["configString"];
          that.firePropertiesChanged(propertyArray);
          
          if(rebuildSupportView){
            createSupportView();
          }
          
      });
    };
    
    // create the alpaca configuration object
    var alpacaConfig = {};
    alpacaConfig = configObject.propertyInterface;
    
    if(!generateInitialPropertyInterface){
      alpacaConfig.postRender = postRendercb;
    }
    
    // update the form with the config 
    $("#alpacaform").html("");
    $("#alpacaform").alpaca( alpacaConfig );
  }
  
  
  function generateSupportView(developerMode){
    // optional parameter developerMode
    if ('undefined' === typeof developerMode) {
        developerMode = false;
    }
   
    
    // create support view if required
    createSupportView();
    
    if(!developerMode){
      setSupportMode();
    }
  }
    
  
  function setDeveloperMode(){
    $("#supportWindow").hide();
    $("#toolbar").hide();
    $("#developerWindow").show();
  }
  
  function setSupportMode(){
    var imgSrc = "";
    $("#btnLock").attr("src", imgSrc);
    $("#btnLock").attr("data", "support");
    
    $("#toolbar").show();
    $("#supportWindow").show();
    $("#developerWindow").hide();
  }
  
  
  /**
   * DESIGN STUDIO GETTER/SETTER FOR CONFIGSTRING
   * - get / set the config editor (developer view)
   * - extract the properties / property interface and generate
   *   the support view (if required)
   * @param {String} value
   *        Configuration string
   * @returns {function}
   *        Configuration string
   */
  this.configString = function(value){
    var editor = ace.edit("editor_config");
    if( value === undefined){
    	
    	// check if there is documentation
        try{
        	var configObject = JSON.parse(editor.getSession().getValue());
        	if(configObject.documentation !== undefined && configObject.documentation !== null && configObject.documentation !== ""){
        		$("#btnDocumentation").show();
        	}else{
        		$("#btnDocumentation").hide();
        	}
        }catch(err){
        	$("#btnDocumentation").hide();
        }
    	
    	return editor.getSession().getValue();
    }
    // set the value in the editor
    editor.getSession().setValue( value );
    
    // check if the additional properties were already initialized
    var propertyInitialized = $('body').data('propertyInitialized');
    if(!propertyInitialized){
      $('body').data('propertyInitialized', true);
      addEventListeners();
    }
    
    // check if there is documentation
    try{
    	var configObject = JSON.parse(value);
    	if(configObject.documentation !== undefined && configObject.documentation !== null && configObject.documentation !== ""){
    		$("#btnDocumentation").show();
    	}else{
    		$("#btnDocumentation").hide();
    	}
    }catch(err){
    	$("#btnDocumentation").hide();
    }
    
    return this;
  };
  
  
  /**
   * DESIGN STUDIO GETTER/SETTER FOR HTMLSTRING
   * - get / set the HTML editor (development view)
   * @param {String} value
   *        HTML string
   * @returns {function}
   *        HTML string
   */
  this.htmlString = function(value){
    var editor = ace.edit("editor_html");
    if( value === undefined){
    	return editor.getSession().getValue();
    }
    editor.getSession().setValue( value );
    return this;
  };
  
  
  /**
   * DESIGN STUDIO GETTER/SETTER FOR CSSSTRING
   * - get / set the CSS editor (development view)
   * @param {String} value
   *        CSS string
   * @returns {function}
   *        CSS string
   */
  this.cssString = function(value){
    var editor = ace.edit("editor_css");
    if( value === undefined){
      return editor.getSession().getValue();
    }
    editor.getSession().setValue( value );
    return this;
  };
  
  
  /**
   * DESIGN STUDIO GETTER/SETTER FOR JSSTRING
   * - get / set the JS editor (development view)
   * @param {String} value
   *        JS string
   * @returns {function}
   *        JS string
   */
  this.jsString = function(value){
    var editor = ace.edit("editor_javascript");
    if( value === undefined){
    	return editor.getSession().getValue();
    }
    editor.getSession().setValue( value );
    return this;
  };
  
  
 
  
});

